const path = require('path')
// 导入 koa 模块与创建服务端实例对象
const Koa = require('koa')
const app = new Koa()
// 导入相关中间件
const koaStatic = require('koa-static') // 处理静态资源
const views = require('koa-views') // 处理动态资源
const json = require('koa-json') // 处理json格式美化
const onerror = require('koa-onerror') // 处理错误监听
const bodyparser = require('koa-bodyparser') // 处理body数据格式化
const logger = require('koa-morgan') // 处理日志
const fs = require('fs')
// 导入保存登录状态的包
const session = require('koa-generic-session')
const redisStore = require('koa-redis')
const { REDIS_CONFIG } = require('./config/db')
const { SECRET } = require('./constants')
// 导入表注册
require('./db/sync')

// 导入相关路由
const index = require('./routes/index')
const user = require('./routes/user')

// 错误处理
onerror(app)

// 注册中间件
app.use(bodyparser({ // body数据解析
  enableTypes: ['json', 'form', 'text']
}))
app.use(json()) // json数据格式美化
app.use(koaStatic(path.join(__dirname, '../public'))) // 静态资源
app.use(views(path.join(__dirname, '/views'), { // 动态资源
  extension: 'pug'
}))
// 注册了记录日志的中间件（写入本地）
const accessLogStream = fs.createWriteStream(path.join(__dirname, 'log/access.log'), { flags: 'a' })
app.use(logger('combined', {
  stream: accessLogStream
}))

// 记录日志（控制台打印）
app.use(async (ctx, next) => {
  const start = new Date()
  await next()
  const ms = new Date() - start
  console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)
})

// 配置保存登录状态的中间件
app.keys = [SECRET] // 用于生成无关紧要的userId的
app.use(session({
  cookie: {
    path: '/',
    httpOnly: true,
    maxAge: 24 * 60 * 60 * 1000
  },
  store: redisStore({
    all: `${REDIS_CONFIG.host}:${REDIS_CONFIG.port}`
  })
}))

// 注册路由
app.use(index.routes(), index.allowedMethods())
app.use(user.routes(), user.allowedMethods())

// 错误处理
app.on('error', (err, ctx) => {
  console.error('server error', err, ctx)
})

module.exports = app
